package com.alibaba.citrus.cr.mn.order.center.facade.function.asynctask.consumer;

import com.alibaba.citrus.cr.mn.order.center.facade.function.asynctask.AsyncTaskCreateService;
import com.alibaba.citrus.cr.mn.order.center.facade.function.asynctask.OrderAsyncTaskListenerConsumerSelector;
import com.alibaba.citrus.cr.mn.order.center.facade.function.common.OrderBizCreateService;
import com.alibaba.citrus.cr.mn.order.center.facade.function.common.SendMsgService;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.BeanConverter;
import com.alibaba.citrus.cr.mn.order.center.facade.function.dataobject.AtomOrderDO;
import com.alibaba.citrus.cr.mn.order.center.facade.repository.AtomOrderQueryRepository;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.epoch.app.crb2btradecenter.domain.order.dto.QueryByOrderNosV2Request;
import com.epoch.app.crb2btradecenter.domain.order.model.Order;
import com.epoch.app.crb2btradecenter.domain.orderline.model.OrderLine;
import com.epoch.app.crb2btradecenter.enums.OrderStatus;
import com.epoch.app.crb2btradecenter.messagetask.model.MessageTask;
import com.epoch.app.crb2btradecenter.model.enums.MessageTaskTypeEnum;
import com.epoch.app.crb2btradecenter.sdo.OrderLineSDO;
import com.epoch.app.crb2btradecenter.sdo.OrderSDO;
import com.epoch.app.crb2btradecenter.sdo.ScItemSDO;
import com.epoch.app.mnordercenter.model.dto.CommonAsyncMessageResponse;
import com.epoch.app.mnordercenter.model.dto.ExchangeOrderAtomBatchCreateRequest;
import com.epoch.app.mnordercenter.model.dto.ExchangeOrderBizBatchCreateRequest;
import com.epoch.app.mnordercenter.orderbaserequest.OrderAtomCreateResponse;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author zhangxiaorui
 * @ClassName OrderAsyncTaskSalesOrderCreateService
 * @description: TODO
 * @date 2023/06/06 11:12
 * @version: 1.0
 */
@Component("orderAsyncTaskExchangeOrderCreateComponent")
public class OrderAsyncTaskExchangeOrderCreateComponent implements OrderAsyncTaskListenerConsumerSelector {
    private static final Log log = Log.getLogger(OrderAsyncTaskExchangeOrderCreateComponent.class);

    @Resource
    private SendMsgService sendMsgService;

    @Resource
    private AsyncTaskCreateService asyncTaskCreateService;

    @Resource
    private AtomOrderQueryRepository atomOrderQueryRepository;

    @Resource(name = "exchangeOrderBizCreateService")
    private OrderBizCreateService<ExchangeOrderBizBatchCreateRequest, ExchangeOrderAtomBatchCreateRequest, OrderAtomCreateResponse> exchangeOrderBizCreateService;

    @Override
    public MessageTaskTypeEnum getMessageTaskType() {
        return MessageTaskTypeEnum.OC_EXCHANGE_ORDER_BATCH_CREATE;
    }

    @Override
    public void doConsumer(String ossTaskContent, MessageTask messageTask) {
        ExchangeOrderBizBatchCreateRequest createRequest = JSONObject.parseObject(ossTaskContent, ExchangeOrderBizBatchCreateRequest.class);
        List<OrderAtomCreateResponse> createResponses = exchangeOrderBizCreateService.batchCreate(createRequest);

        log.info("OrderAsyncTask_doCreate_ExchangeOrder result={}", JSONArray.toJSONString(createResponses));

        // 发送kafka消息通知应用端处理结果
//        sendMsgService.sendMsgToNYK(convertMnSideRequests(createResponses));
        CommonAsyncMessageResponse commonAsyncMessageResponse = convertCommonAsyncMessageResponse(messageTask.getBatchNo(), createRequest.getFromSys(), createRequest.getBusinessUnitCode(), createResponses);
        sendMsgService.sendMsgToSendKafka(commonAsyncMessageResponse);
        log.info("OrderAsyncTaskExchangeOrderCreateComponent#doConsumer sendMsgToSendKafka message={}", commonAsyncMessageResponse);

        // 发消息预占库存
        sendMsgToInventoryOccupy(createResponses);

        // 上传原子结果
        asyncTaskCreateService.appendAsyncTaskHandleResult(JSONArray.toJSONString(createResponses),
                messageTask.getBatchNo(), messageTask);
    }

    @Override
    public void sendOccupyInventoryOccupyMsg(List<String> bizOrderId) {
        QueryByOrderNosV2Request request = new QueryByOrderNosV2Request();
        request.setSalesOrderNo(bizOrderId);
        List<AtomOrderDO> listResult = atomOrderQueryRepository.queryByOrderBizIds(request, false);

        if (CollectionUtils.isNotEmpty(listResult)) {
            // 过滤待提交数据，待提交数据不进行推送SAP
            List<AtomOrderDO> dos = listResult.stream()
                    .filter(p -> !Objects.equals(p.getOrder().getStatus(), OrderStatus.BEFORE_SUBMIT.getCode()))
                    .collect(Collectors.toList());

            log.info("sendMsgToInventoryOccupy_WAIT_SEND result={}", JSONArray.toJSONString(dos));
            List<OrderSDO> orderSubmitList = dos.stream().map(this::convertTradeOrderSDO).collect(Collectors.toList());

            // 发消息预占库存
            sendMsgService.sendMsgToInventoryOccupy(orderSubmitList);
        }
    }

    private void sendMsgToInventoryOccupy(List<OrderAtomCreateResponse> createResponses) {

        // 过滤创建失败的单据
        List<OrderAtomCreateResponse> successCreateResponses = Optional.ofNullable(createResponses).orElse(Lists.newArrayList())
                .stream()
                .filter(p -> StringUtils.isBlank(p.getErrorCode()))
                .collect(Collectors.toList());

        List<String> salesOrderNos = successCreateResponses.stream().map(OrderAtomCreateResponse::getSalesOrderNo)
                .filter(StringUtils::isNotBlank)
                .distinct().collect(Collectors.toList());

        if (CollectionUtils.isEmpty(salesOrderNos)) {
            log.info("sendMsgToInventoryOccupy_DATA_EMPTY_SKIP result={}", JSONArray.toJSONString(createResponses));
            return;
        }
        sendOccupyInventoryOccupyMsg(salesOrderNos);
    }

    /**
     * 适配历史逻辑转为 trade应用下的 com.epoch.app.crb2btradecenter.sdo
     *
     * @param atomOrderDO
     * @return
     */
    private OrderSDO convertTradeOrderSDO(AtomOrderDO atomOrderDO) {
        Order order = atomOrderDO.getOrder();
        List<OrderLine> orderLines = atomOrderDO.getOrderLines();

        List<OrderLineSDO> orderLineSDOS = Optional.ofNullable(orderLines).orElse(Lists.newArrayList()).stream().map(orderLine -> {
            ScItemSDO scItemSDO = new ScItemSDO();

            BeanUtils.copyProperties(orderLine, scItemSDO);

            scItemSDO.setSaleUnit(orderLine.getSaleUnit());
            scItemSDO.setSaleUnitName(orderLine.getSaleUnitName());
            scItemSDO.setQuantity(orderLine.getQuantity());
            scItemSDO.setScItemId(orderLine.getScItemId());
            scItemSDO.setScItemOutCode(orderLine.getScItemOutCode());
            scItemSDO.setScItemTitle(orderLine.getScItemTitle());
            scItemSDO.setUnitConvert(orderLine.getUnitConvert());
            scItemSDO.setUnitPrice(StringUtils.isBlank(orderLine.getUnitPrice()) ? null : Long.parseLong(orderLine.getUnitPrice()));

            OrderLineSDO orderLineSDO = new OrderLineSDO();
            BeanUtils.copyProperties(orderLine, orderLineSDO);

            orderLineSDO.setId(String.valueOf(orderLine.getId()));
            orderLineSDO.setMainOrderId(orderLine.getMainOrderId());
            orderLineSDO.setMainOrderBizId(orderLine.getMainOrderBizId());
            orderLineSDO.setOrderLineTag(orderLine.getOrderLineTag());
            orderLineSDO.setScItemSDO(scItemSDO);

            orderLineSDO.setRefuseReasonCode(orderLine.getRefuseReasonCode());//标记需要释放的
            orderLineSDO.setRefuseReasonName(orderLine.getRefuseReasonName());
            return orderLineSDO;
        }).collect(Collectors.toList());

        OrderSDO orderSDO = new OrderSDO();

        BeanConverter.convert(order, orderSDO);

        orderSDO.setId(String.valueOf(order.getId()));
        orderSDO.setOrderBizId(order.getOrderBizId());
        orderSDO.setFrontOrderId(order.getFrontOrderId());
        orderSDO.setStatus(order.getStatus());
        orderSDO.setBizCode(order.getBizCode());
        orderSDO.setBusinessCode(order.getBusinessCode());
        orderSDO.setBisUnitCode(order.getBisUnitCode());
        orderSDO.setProductGroupCode(order.getProductGroupCode());
        orderSDO.setProductGroupName(order.getProductGroupName());
        orderSDO.setWareHouseCode(order.getWareHouseCode());
        orderSDO.setWareHouseName(order.getWareHouseName());
        orderSDO.setOrderType(order.getOrderType());
        orderSDO.setOrderTypeName(order.getOrderTypeName());
        orderSDO.setOrderTag(order.getOrderTag());
        orderSDO.setReceiveWareHouseCode(order.getReceiveWareHouseCode());
        orderSDO.setReceiveWareHouseName(order.getReceiveWareHouseName());
        orderSDO.setSourceOrderNo(order.getSourceOrderNo());
        orderSDO.setFromSys(order.getFromSys());
        orderSDO.setReceiveAddressCode(order.getReceiveAddressCode());
        orderSDO.setOrderLineSDOS(orderLineSDOS);
        return orderSDO;
    }
}
